use crate::handlers::{
    ApiHandlers, MetricsRequest, MetricsResponse, HistoricalMetricsRequest, 
    HistoricalMetricsResponse, DashboardConfig, AlertRule, Alert
};
use axum::{
    extract::{Path, Query, State},
    http::StatusCode,
    response::Json,
    routing::{get, post, put, delete},
    Router,
};
use serde_json::Value;
use std::collections::HashMap;
use std::sync::Arc;
use tracing::{debug, error, info};

/// Dashboard API router
pub fn create_dashboard_router(handlers: Arc<ApiHandlers>) -> Router {
    Router::new()
        // Metrics endpoints
        .route("/api/v1/dashboard/metrics", get(get_metrics))
        .route("/api/v1/dashboard/metrics/historical", get(get_historical_metrics))
        
        // Dashboard configuration endpoints
        .route("/api/v1/dashboard/configs", get(list_dashboards))
        .route("/api/v1/dashboard/configs", post(create_dashboard))
        .route("/api/v1/dashboard/configs/:id", get(get_dashboard))
        .route("/api/v1/dashboard/configs/:id", put(update_dashboard))
        .route("/api/v1/dashboard/configs/:id", delete(delete_dashboard))
        
        // Alert rule endpoints
        .route("/api/v1/dashboard/alerts/rules", get(list_alert_rules))
        .route("/api/v1/dashboard/alerts/rules", post(create_alert_rule))
        .route("/api/v1/dashboard/alerts/rules/:id", get(get_alert_rule))
        .route("/api/v1/dashboard/alerts/rules/:id", put(update_alert_rule))
        .route("/api/v1/dashboard/alerts/rules/:id", delete(delete_alert_rule))
        
        // Active alerts endpoints
        .route("/api/v1/dashboard/alerts", get(get_active_alerts))
        .route("/api/v1/dashboard/alerts/:id/acknowledge", post(acknowledge_alert))
        
        .with_state(handlers)
}

// Metrics endpoints

async fn get_metrics(
    State(handlers): State<Arc<ApiHandlers>>,
    Query(params): Query<HashMap<String, String>>,
) -> Result<Json<MetricsResponse>, StatusCode> {
    debug!("GET /api/v1/dashboard/metrics with params: {:?}", params);

    let request = MetricsRequest {
        file_paths: params.get("file_paths")
            .map(|s| s.split(',').map(|s| s.to_string()).collect()),
        time_range: None, // TODO: Parse time range from params
        metrics: params.get("metrics")
            .map(|s| s.split(',').map(|s| s.to_string()).collect()),
    };

    match handlers.get_metrics(request).await {
        Ok(response) => {
            info!("Successfully retrieved {} metrics", response.data.len());
            Ok(Json(response))
        }
        Err(e) => {
            error!("Failed to get metrics: {}", e);
            Err(StatusCode::INTERNAL_SERVER_ERROR)
        }
    }
}

async fn get_historical_metrics(
    State(handlers): State<Arc<ApiHandlers>>,
    Query(params): Query<HashMap<String, String>>,
) -> Result<Json<HistoricalMetricsResponse>, StatusCode> {
    debug!("GET /api/v1/dashboard/metrics/historical with params: {:?}", params);

    let metric = params.get("metric")
        .ok_or(StatusCode::BAD_REQUEST)?
        .clone();

    let start = params.get("start")
        .ok_or(StatusCode::BAD_REQUEST)?
        .clone();

    let end = params.get("end")
        .ok_or(StatusCode::BAD_REQUEST)?
        .clone();

    let interval = params.get("interval")
        .unwrap_or(&"1h".to_string())
        .clone();

    let request = HistoricalMetricsRequest {
        file_path: params.get("file_path").cloned(),
        metric,
        time_range: crate::handlers::TimeRange {
            start,
            end,
            interval: Some(interval.clone()),
        },
        interval,
    };

    match handlers.get_historical_metrics(request).await {
        Ok(response) => {
            info!("Successfully retrieved historical metrics for {}", response.metric);
            Ok(Json(response))
        }
        Err(e) => {
            error!("Failed to get historical metrics: {}", e);
            Err(StatusCode::INTERNAL_SERVER_ERROR)
        }
    }
}

// Dashboard endpoints

async fn list_dashboards(
    State(handlers): State<Arc<ApiHandlers>>,
) -> Result<Json<Vec<DashboardConfig>>, StatusCode> {
    debug!("GET /api/v1/dashboard/configs");

    match handlers.list_dashboard_configs().await {
        Ok(dashboards) => {
            info!("Successfully retrieved {} dashboards", dashboards.len());
            Ok(Json(dashboards))
        }
        Err(e) => {
            error!("Failed to list dashboards: {}", e);
            Err(StatusCode::INTERNAL_SERVER_ERROR)
        }
    }
}

async fn get_dashboard(
    State(handlers): State<Arc<ApiHandlers>>,
    Path(id): Path<String>,
) -> Result<Json<DashboardConfig>, StatusCode> {
    debug!("GET /api/v1/dashboard/configs/{}", id);

    match handlers.get_dashboard_config(&id).await {
        Ok(Some(dashboard)) => {
            info!("Successfully retrieved dashboard: {}", id);
            Ok(Json(dashboard))
        }
        Ok(None) => {
            debug!("Dashboard not found: {}", id);
            Err(StatusCode::NOT_FOUND)
        }
        Err(e) => {
            error!("Failed to get dashboard {}: {}", id, e);
            Err(StatusCode::INTERNAL_SERVER_ERROR)
        }
    }
}

async fn create_dashboard(
    State(handlers): State<Arc<ApiHandlers>>,
    Json(config): Json<DashboardConfig>,
) -> Result<Json<DashboardConfig>, StatusCode> {
    debug!("POST /api/v1/dashboard/configs");

    match handlers.save_dashboard_config(config).await {
        Ok(dashboard) => {
            info!("Successfully created dashboard: {}", dashboard.id);
            Ok(Json(dashboard))
        }
        Err(e) => {
            error!("Failed to create dashboard: {}", e);
            Err(StatusCode::INTERNAL_SERVER_ERROR)
        }
    }
}

async fn update_dashboard(
    State(handlers): State<Arc<ApiHandlers>>,
    Path(id): Path<String>,
    Json(mut config): Json<DashboardConfig>,
) -> Result<Json<DashboardConfig>, StatusCode> {
    debug!("PUT /api/v1/dashboard/configs/{}", id);

    // Ensure the ID matches
    config.id = id;
    config.updated_at = chrono::Utc::now().to_rfc3339();

    match handlers.save_dashboard_config(config).await {
        Ok(dashboard) => {
            info!("Successfully updated dashboard: {}", dashboard.id);
            Ok(Json(dashboard))
        }
        Err(e) => {
            error!("Failed to update dashboard: {}", e);
            Err(StatusCode::INTERNAL_SERVER_ERROR)
        }
    }
}

async fn delete_dashboard(
    State(handlers): State<Arc<ApiHandlers>>,
    Path(id): Path<String>,
) -> Result<StatusCode, StatusCode> {
    debug!("DELETE /api/v1/dashboard/configs/{}", id);

    match handlers.delete_dashboard_config(&id).await {
        Ok(true) => {
            info!("Successfully deleted dashboard: {}", id);
            Ok(StatusCode::NO_CONTENT)
        }
        Ok(false) => {
            debug!("Dashboard not found: {}", id);
            Err(StatusCode::NOT_FOUND)
        }
        Err(e) => {
            error!("Failed to delete dashboard {}: {}", id, e);
            Err(StatusCode::INTERNAL_SERVER_ERROR)
        }
    }
}

// Alert rule endpoints

async fn list_alert_rules(
    State(handlers): State<Arc<ApiHandlers>>,
) -> Result<Json<Vec<AlertRule>>, StatusCode> {
    debug!("GET /api/v1/dashboard/alerts/rules");

    match handlers.list_alert_rules().await {
        Ok(rules) => {
            info!("Successfully retrieved {} alert rules", rules.len());
            Ok(Json(rules))
        }
        Err(e) => {
            error!("Failed to list alert rules: {}", e);
            Err(StatusCode::INTERNAL_SERVER_ERROR)
        }
    }
}

async fn get_alert_rule(
    State(handlers): State<Arc<ApiHandlers>>,
    Path(id): Path<String>,
) -> Result<Json<AlertRule>, StatusCode> {
    debug!("GET /api/v1/dashboard/alerts/rules/{}", id);

    match handlers.get_alert_rule(&id).await {
        Ok(Some(rule)) => {
            info!("Successfully retrieved alert rule: {}", id);
            Ok(Json(rule))
        }
        Ok(None) => {
            debug!("Alert rule not found: {}", id);
            Err(StatusCode::NOT_FOUND)
        }
        Err(e) => {
            error!("Failed to get alert rule {}: {}", id, e);
            Err(StatusCode::INTERNAL_SERVER_ERROR)
        }
    }
}

async fn create_alert_rule(
    State(handlers): State<Arc<ApiHandlers>>,
    Json(rule): Json<AlertRule>,
) -> Result<Json<AlertRule>, StatusCode> {
    debug!("POST /api/v1/dashboard/alerts/rules");

    match handlers.save_alert_rule(rule).await {
        Ok(rule) => {
            info!("Successfully created alert rule: {}", rule.id);
            Ok(Json(rule))
        }
        Err(e) => {
            error!("Failed to create alert rule: {}", e);
            Err(StatusCode::INTERNAL_SERVER_ERROR)
        }
    }
}

async fn update_alert_rule(
    State(handlers): State<Arc<ApiHandlers>>,
    Path(id): Path<String>,
    Json(mut rule): Json<AlertRule>,
) -> Result<Json<AlertRule>, StatusCode> {
    debug!("PUT /api/v1/dashboard/alerts/rules/{}", id);

    // Ensure the ID matches
    rule.id = id;
    rule.updated_at = chrono::Utc::now().to_rfc3339();

    match handlers.save_alert_rule(rule).await {
        Ok(rule) => {
            info!("Successfully updated alert rule: {}", rule.id);
            Ok(Json(rule))
        }
        Err(e) => {
            error!("Failed to update alert rule: {}", e);
            Err(StatusCode::INTERNAL_SERVER_ERROR)
        }
    }
}

async fn delete_alert_rule(
    State(handlers): State<Arc<ApiHandlers>>,
    Path(id): Path<String>,
) -> Result<StatusCode, StatusCode> {
    debug!("DELETE /api/v1/dashboard/alerts/rules/{}", id);

    match handlers.delete_alert_rule(&id).await {
        Ok(true) => {
            info!("Successfully deleted alert rule: {}", id);
            Ok(StatusCode::NO_CONTENT)
        }
        Ok(false) => {
            debug!("Alert rule not found: {}", id);
            Err(StatusCode::NOT_FOUND)
        }
        Err(e) => {
            error!("Failed to delete alert rule {}: {}", id, e);
            Err(StatusCode::INTERNAL_SERVER_ERROR)
        }
    }
}

// Active alerts endpoints

async fn get_active_alerts(
    State(handlers): State<Arc<ApiHandlers>>,
) -> Result<Json<Vec<Alert>>, StatusCode> {
    debug!("GET /api/v1/dashboard/alerts");

    match handlers.get_active_alerts().await {
        Ok(alerts) => {
            info!("Successfully retrieved {} active alerts", alerts.len());
            Ok(Json(alerts))
        }
        Err(e) => {
            error!("Failed to get active alerts: {}", e);
            Err(StatusCode::INTERNAL_SERVER_ERROR)
        }
    }
}

async fn acknowledge_alert(
    State(handlers): State<Arc<ApiHandlers>>,
    Path(id): Path<String>,
) -> Result<StatusCode, StatusCode> {
    debug!("POST /api/v1/dashboard/alerts/{}/acknowledge", id);

    match handlers.acknowledge_alert(&id).await {
        Ok(true) => {
            info!("Successfully acknowledged alert: {}", id);
            Ok(StatusCode::NO_CONTENT)
        }
        Ok(false) => {
            debug!("Alert not found: {}", id);
            Err(StatusCode::NOT_FOUND)
        }
        Err(e) => {
            error!("Failed to acknowledge alert {}: {}", id, e);
            Err(StatusCode::INTERNAL_SERVER_ERROR)
        }
    }
}
